package com.cy.pj.goods.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository //是spring框架中定义的一个描述数据层baen对象的注解
public class DefaultGoodsDao implements GoodsDao {

    @Autowired
    private DataSource dataSource;

    //初始化一个日志对象(所有类都在org.slf4j包中)
    //在哪个类创建日志对象,我们的getLogger方法内部的对象就是哪个类的字节码对象
    private static final Logger log = LoggerFactory.getLogger(DefaultGoodsDao.class);

    //行映射
    Map<String, Object> rowMap(ResultSetMetaData metaData, ResultSet rs) throws SQLException {
        Map<String, Object> map = new HashMap<>();
        for (int i = 1; i <= metaData.getColumnCount(); i++) {
            map.put(metaData.getColumnName(i), rs.getObject(metaData.getColumnName(i)));
        }
        return map;
    }

    //释放资源
    public void close(ResultSet rs, Statement statement, Connection connection) {
        if (rs != null) try {
            rs.close();
        } catch (SQLException e1) {
        }
        if (statement != null) try {
            statement.close();
        } catch (SQLException e1) {
        }
        if (connection != null) try {
            connection.close();
        } catch (SQLException e1) {
        }
    }

    @Override
    public List<Map<String, Object>> findGoods() {
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        String sql = "select * from tb_goods";
        try {
            //1,获取连接
            connection = dataSource.getConnection();
            //2,创建statement
            statement = connection.createStatement();
            //3,发送sql
            rs = statement.executeQuery(sql);
            //4,处理结果
            List<Map<String, Object>> list = new ArrayList<>();
            ResultSetMetaData metaData = rs.getMetaData();//获取结果集中的元数据(表头)
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
//               map.put("id", rs.getInt("id"));
//               map.put("name", rs.getString("name"));
//               map.put("remark", rs.getString("remark"));
//               map.put("createdTime", rs.getTimestamp("createdTime"));
//               list.add(map);
                //映射2
                list.add(rowMap(metaData, rs));
            }
            return list;
        } catch (Exception e) {
//           e.printStackTrace();
//           return null;
            log.error("查询异常,{}", e.getMessage());
            throw new RuntimeException("数据查询失败"+e.getMessage());
        } finally {
            //5,释放资源
//           if(rs!=null)try{rs.close();}catch(SQLException e1){}
//           if(statement!=null)try{statement.close();}catch(SQLException e1){}
//           if(connection!=null)try{connection.close();}catch(SQLException e1){}
            close(rs, statement, connection);
        }
    }

}
/*
    优点:
    1)代码简单(步骤固定)
    2)使用了连接池,优化了建立连接的过程,从池中获取连接,提高了数据访问性能
    3)使用了Map做映射,简化了pojo对象定义
    缺点:
    1)可重用行差(例如次元释放代码,可以封装)
    2)行映射不灵活
    3)异常的处理不能简单的打印一下就返回null
    4)Map封装数据时值的类型不可控(建议后续修改为pojo对象)
    5)对共性模板应该进行封装,特性代码进行提取
 */